#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <assert.h>
#include "../comm/log.hpp"
#include "../comm/util.hpp"
// 1.将本地题库加载到内存中
// 2.提供对外访问的接口


/*  文件 版本*/
namespace ns_model
{
    using namespace std;
    using namespace ns_log;
    using namespace ns_util;

    struct Question
    {
        string number; // 题目编号
        string tile;   // 题目标题
        string star;   // 题目难度
        int cpu_limit; // 运行时间限制
        int mem_limit; // 运行空间限制
        string desc;   // 题目描述
        string header; // 题目预代码
        string test;   // 测试文件
    };
    
    const string questions_list = "./questions/questions.list";
    const string questions_path = "./questions";
   
    class Model
    {
    public:
        Model()
        {
            assert(loadAllQuestonsList(questions_list));
        }
        bool loadAllQuestonsList(const string& list)
        {
            //加载题库
            ifstream in(list);
            if(!in.is_open())
            {
                LOG(Level::FATAL)<<"题库加载失败"<<"\n";
                return false;
            }
            //读取list
            string line;
            while(getline(in,line))
            {
                vector<string> temp;
                Question question;
                StringUtil::splitString(line,&temp," ");

                if(temp.size() != 5)
                {
                    LOG(Level::WARNING)<<"题库部分题目加载出错,请检查题目格式"<<"\n";
                    continue;
                }
                question.number = temp[0];
                question.tile = temp[1];
                question.star = temp[2];
                question.cpu_limit = atoi(temp[3].c_str());
                question.mem_limit = atoi(temp[4].c_str());

                string path = questions_path;
                path += "/";
                path += question.number;

                FileUtil::readFile(path + "/" + "desc.txt",&question.desc,true);
                FileUtil::readFile(path + "/" +  "header.cpp",&question.header,true);
                FileUtil::readFile(path + "/" + "test.cpp",&question.test,true);

                _questions.insert({question.number,question});
                 
            }
            LOG(Level::INFO)<<"题库加载完毕,共加载了"<<_questions.size()<<"道题"<<"\n";
            in.close();
            return true;
        }

        bool getAllQuestions(vector<Question>* qs)
        {
            if(_questions.empty())
            {
                LOG(Level::ERROR)<<"获取题库失败"<<endl;
                return false;
            }
            for(auto q: _questions)
            {
                qs->push_back(q.second);
            }
            return true;
        }
        bool getOneQuestion(const std::string& number,Question* q)
        {
            auto it = _questions.find(number);
            if(it == _questions.end())
            {
                LOG(Level::ERROR)<<"获取题目失败,题号为:"<<number<<endl;
                return false;
            }
            *q = it->second;
            return true;
        }
        ~Model()
        {
        }

    private:
        unordered_map<string,Question> _questions;
    };
}